package org.xbill.DNS;

import java.io.IOException;
import java.io.InterruptedIOException;
import java.io.PrintStream;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

public class ExtendedResolver
  implements Resolver
{
  private static final int quantum = 5;
  private int lbStart;
  private boolean loadBalance = false;
  private List resolvers;
  private int retries;

  public ExtendedResolver()
    throws UnknownHostException
  {
    this.lbStart = 0;
    this.retries = 3;
    init();
    String[] arrayOfString = ResolverConfig.getCurrentConfig().servers();
    if (arrayOfString != null)
    {
      i = 0;
      if (i >= arrayOfString.length);
    }
    while (true)
    {
      while (true)
      {
        return;
        SimpleResolver localSimpleResolver = new SimpleResolver(arrayOfString[i]);
        localSimpleResolver.setTimeout(5);
        this.resolvers.add(localSimpleResolver);
        ++i;
      }
      this.resolvers.add(new SimpleResolver());
    }
  }

  public ExtendedResolver(String[] paramArrayOfString)
    throws UnknownHostException
  {
    this.lbStart = 0;
    this.retries = 3;
    init();
    int i = 0;
    while (true)
    {
      if (i >= paramArrayOfString.length)
        return;
      SimpleResolver localSimpleResolver = new SimpleResolver(paramArrayOfString[i]);
      localSimpleResolver.setTimeout(5);
      this.resolvers.add(localSimpleResolver);
      ++i;
    }
  }

  public ExtendedResolver(Resolver[] paramArrayOfResolver)
    throws UnknownHostException
  {
    this.lbStart = 0;
    this.retries = 3;
    init();
    int i = 0;
    while (true)
    {
      if (i >= paramArrayOfResolver.length)
        return;
      this.resolvers.add(paramArrayOfResolver[i]);
      ++i;
    }
  }

  private void init()
  {
    this.resolvers = new ArrayList();
  }

  public void addResolver(Resolver paramResolver)
  {
    this.resolvers.add(paramResolver);
  }

  public void deleteResolver(Resolver paramResolver)
  {
    this.resolvers.remove(paramResolver);
  }

  public Resolver getResolver(int paramInt)
  {
    Resolver localResolver;
    if (paramInt < this.resolvers.size())
      localResolver = (Resolver)this.resolvers.get(paramInt);
    while (true)
    {
      return localResolver;
      localResolver = null;
    }
  }

  public Resolver[] getResolvers()
  {
    return ((Resolver[])this.resolvers.toArray(new Resolver[this.resolvers.size()]));
  }

  public Message send(Message paramMessage)
    throws IOException
  {
    return new Resolution(this, paramMessage).start();
  }

  public Object sendAsync(Message paramMessage, ResolverListener paramResolverListener)
  {
    Resolution localResolution = new Resolution(this, paramMessage);
    localResolution.startAsync(paramResolverListener);
    return localResolution;
  }

  public void setEDNS(int paramInt)
  {
    int i = 0;
    while (true)
    {
      if (i >= this.resolvers.size())
        return;
      ((Resolver)this.resolvers.get(i)).setEDNS(paramInt);
      ++i;
    }
  }

  public void setEDNS(int paramInt1, int paramInt2, int paramInt3, List paramList)
  {
    int i = 0;
    while (true)
    {
      if (i >= this.resolvers.size())
        return;
      ((Resolver)this.resolvers.get(i)).setEDNS(paramInt1, paramInt2, paramInt3, paramList);
      ++i;
    }
  }

  public void setIgnoreTruncation(boolean paramBoolean)
  {
    int i = 0;
    while (true)
    {
      if (i >= this.resolvers.size())
        return;
      ((Resolver)this.resolvers.get(i)).setIgnoreTruncation(paramBoolean);
      ++i;
    }
  }

  public void setLoadBalance(boolean paramBoolean)
  {
    this.loadBalance = paramBoolean;
  }

  public void setPort(int paramInt)
  {
    int i = 0;
    while (true)
    {
      if (i >= this.resolvers.size())
        return;
      ((Resolver)this.resolvers.get(i)).setPort(paramInt);
      ++i;
    }
  }

  public void setRetries(int paramInt)
  {
    this.retries = paramInt;
  }

  public void setTCP(boolean paramBoolean)
  {
    int i = 0;
    while (true)
    {
      if (i >= this.resolvers.size())
        return;
      ((Resolver)this.resolvers.get(i)).setTCP(paramBoolean);
      ++i;
    }
  }

  public void setTSIGKey(TSIG paramTSIG)
  {
    int i = 0;
    while (true)
    {
      if (i >= this.resolvers.size())
        return;
      ((Resolver)this.resolvers.get(i)).setTSIGKey(paramTSIG);
      ++i;
    }
  }

  public void setTimeout(int paramInt)
  {
    setTimeout(paramInt, 0);
  }

  public void setTimeout(int paramInt1, int paramInt2)
  {
    int i = 0;
    while (true)
    {
      if (i >= this.resolvers.size())
        return;
      ((Resolver)this.resolvers.get(i)).setTimeout(paramInt1, paramInt2);
      ++i;
    }
  }

  private static class Resolution
  implements ResolverListener
  {
    boolean done;
    Object[] inprogress;
    ResolverListener listener;
    int outstanding;
    Message query;
    Resolver[] resolvers;
    Message response;
    int retries;
    int[] sent;
    Throwable thrown;

    public Resolution(ExtendedResolver paramExtendedResolver, Message paramMessage)
    {
      List localList = ExtendedResolver.access$0(paramExtendedResolver);
      this.resolvers = ((Resolver[])localList.toArray(new Resolver[localList.size()]));
      if (ExtendedResolver.access$1(paramExtendedResolver))
      {
        i = this.resolvers.length;
        int j = ExtendedResolver.access$2(paramExtendedResolver);
        ExtendedResolver.access$3(paramExtendedResolver, j + 1);
        k = j % i;
        if (ExtendedResolver.access$2(paramExtendedResolver) > i)
          ExtendedResolver.access$3(paramExtendedResolver, ExtendedResolver.access$2(paramExtendedResolver) % i);
        if (k > 0)
        {
          arrayOfResolver = new Resolver[i];
          l = 0;
        }
      }
      while (true)
      {
        if (l >= i)
        {
          this.resolvers = arrayOfResolver;
          this.sent = new int[this.resolvers.length];
          this.inprogress = new Object[this.resolvers.length];
          this.retries = ExtendedResolver.access$4(paramExtendedResolver);
          this.query = paramMessage;
          return;
        }
        int i1 = (l + k) % i;
        arrayOfResolver[l] = this.resolvers[i1];
        ++l;
      }
    }

    public void handleException(Object paramObject, Exception paramException)
    {
      if (Options.check("verbose"))
        System.err.println("ExtendedResolver: got " + paramException);
      monitorenter;
      while (true)
      {
        try
        {
          this.outstanding -= 1;
          if (this.done)
          {
            monitorexit;
            break label333:
            if (i >= this.inprogress.length)
            {
              if (i != this.inprogress.length)
                break label101;
              label333: label213: label221: label101: monitorexit;
            }
          }
        }
        finally
        {
          while (true)
          {
            do
            {
              monitorexit;
              throw localObject;
            }
            while (this.inprogress[i] == paramObject);
            ++i;
          }
          int j = 0;
          if ((this.sent[i] == 1) && (i < this.resolvers.length - 1))
            j = 1;
          if (paramException instanceof InterruptedIOException)
          {
            if (this.sent[i] < this.retries)
              send(i);
            if (this.thrown == null)
              this.thrown = paramException;
          }
          while (true)
          {
            while (true)
            {
              do
              {
                if (!(this.done))
                  break label221;
                monitorexit;
                break label333:
                if (!(paramException instanceof SocketException))
                  break label213;
              }
              while ((this.thrown != null) && (!(this.thrown instanceof InterruptedIOException)));
              this.thrown = paramException;
            }
            this.thrown = paramException;
          }
          if (j != 0)
            send(i + 1);
          if (this.done)
          {
            monitorexit;
          }
          else if (this.outstanding == 0)
          {
            this.done = true;
            if (this.listener == null)
            {
              super.notifyAll();
              monitorexit;
            }
          }
          else if (!(this.done))
          {
            monitorexit;
          }
          else
          {
            monitorexit;
            if (!(this.thrown instanceof Exception))
              this.thrown = new RuntimeException(this.thrown.getMessage());
          }
        }
        int i = 0;
      }
    }

    // ERROR //
    public void receiveMessage(Object paramObject, Message paramMessage)
    {
      // Byte code:
      //   0: ldc 78
      //   2: invokestatic 84	org/xbill/DNS/Options:check	(Ljava/lang/String;)Z
      //   5: ifeq +11 -> 16
      //   8: getstatic 90	java/lang/System:err	Ljava/io/PrintStream;
      //   11: ldc 145
      //   13: invokevirtual 110	java/io/PrintStream:println	(Ljava/lang/String;)V
      //   16: aload_0
      //   17: monitorenter
      //   18: aload_0
      //   19: getfield 114	org/xbill/DNS/ExtendedResolver$Resolution:done	Z
      //   22: ifeq +8 -> 30
      //   25: aload_0
      //   26: monitorexit
      //   27: goto +50 -> 77
      //   30: aload_0
      //   31: aload_2
      //   32: putfield 147	org/xbill/DNS/ExtendedResolver$Resolution:response	Lorg/xbill/DNS/Message;
      //   35: aload_0
      //   36: iconst_1
      //   37: putfield 114	org/xbill/DNS/ExtendedResolver$Resolution:done	Z
      //   40: aload_0
      //   41: getfield 126	org/xbill/DNS/ExtendedResolver$Resolution:listener	Lorg/xbill/DNS/ResolverListener;
      //   44: ifnonnull +17 -> 61
      //   47: aload_0
      //   48: invokevirtual 129	java/lang/Object:notifyAll	()V
      //   51: aload_0
      //   52: monitorexit
      //   53: goto +24 -> 77
      //   56: astore_3
      //   57: aload_0
      //   58: monitorexit
      //   59: aload_3
      //   60: athrow
      //   61: aload_0
      //   62: monitorexit
      //   63: aload_0
      //   64: getfield 126	org/xbill/DNS/ExtendedResolver$Resolution:listener	Lorg/xbill/DNS/ResolverListener;
      //   67: aload_0
      //   68: aload_0
      //   69: getfield 147	org/xbill/DNS/ExtendedResolver$Resolution:response	Lorg/xbill/DNS/Message;
      //   72: invokeinterface 149 3 0
      //   77: return
      //
      // Exception table:
      //   from	to	target	type
      //   18	59	56	finally
      //   61	63	56	finally
    }

    // ERROR //
    public void send(int paramInt)
    {
      // Byte code:
      //   0: aload_0
      //   1: getfield 65	org/xbill/DNS/ExtendedResolver$Resolution:sent	[I
      //   4: astore_2
      //   5: aload_2
      //   6: iload_1
      //   7: iconst_1
      //   8: aload_2
      //   9: iload_1
      //   10: iaload
      //   11: iadd
      //   12: iastore
      //   13: aload_0
      //   14: iconst_1
      //   15: aload_0
      //   16: getfield 112	org/xbill/DNS/ExtendedResolver$Resolution:outstanding	I
      //   19: iadd
      //   20: putfield 112	org/xbill/DNS/ExtendedResolver$Resolution:outstanding	I
      //   23: aload_0
      //   24: getfield 67	org/xbill/DNS/ExtendedResolver$Resolution:inprogress	[Ljava/lang/Object;
      //   27: iload_1
      //   28: aload_0
      //   29: getfield 51	org/xbill/DNS/ExtendedResolver$Resolution:resolvers	[Lorg/xbill/DNS/Resolver;
      //   32: iload_1
      //   33: aaload
      //   34: aload_0
      //   35: getfield 74	org/xbill/DNS/ExtendedResolver$Resolution:query	Lorg/xbill/DNS/Message;
      //   38: aload_0
      //   39: invokeinterface 153 3 0
      //   44: aastore
      //   45: return
      //   46: astore_3
      //   47: aload_0
      //   48: monitorenter
      //   49: aload_0
      //   50: aload_3
      //   51: putfield 122	org/xbill/DNS/ExtendedResolver$Resolution:thrown	Ljava/lang/Throwable;
      //   54: aload_0
      //   55: iconst_1
      //   56: putfield 114	org/xbill/DNS/ExtendedResolver$Resolution:done	Z
      //   59: aload_0
      //   60: getfield 126	org/xbill/DNS/ExtendedResolver$Resolution:listener	Lorg/xbill/DNS/ResolverListener;
      //   63: ifnonnull +19 -> 82
      //   66: aload_0
      //   67: invokevirtual 129	java/lang/Object:notifyAll	()V
      //   70: aload_0
      //   71: monitorexit
      //   72: goto -27 -> 45
      //   75: astore 4
      //   77: aload_0
      //   78: monitorexit
      //   79: aload 4
      //   81: athrow
      //   82: aload_0
      //   83: monitorexit
      //   84: goto -39 -> 45
      //
      // Exception table:
      //   from	to	target	type
      //   23	45	46	java/lang/Throwable
      //   49	79	75	finally
      //   82	84	75	finally
    }

    public Message start()
      throws IOException
    {
      Message localMessage1;
      int[] arrayOfInt;
      try
      {
        arrayOfInt = this.sent;
        arrayOfInt[0] = (1 + arrayOfInt[0]);
        this.outstanding = (1 + this.outstanding);
        this.inprogress[0] = new Object();
        Message localMessage2 = this.resolvers[0].send(this.query);
        localMessage1 = localMessage2;
        return localMessage1;
      }
      catch (Exception localException)
      {
        handleException(this.inprogress[0], localException);
        monitorenter;
      }
      try
      {
      }
      finally
      {
        try
        {
          label77: super.wait();
        }
        catch (InterruptedException localInterruptedException)
        {
          break label77:
          localObject = finally;
          monitorexit;
          throw localObject;
        }
        if (this.thrown instanceof IOException)
          throw ((IOException)this.thrown);
        if (this.thrown instanceof RuntimeException)
          throw ((RuntimeException)this.thrown);
        if (this.thrown instanceof Error)
          throw ((Error)this.thrown);
      }
    }

    public void startAsync(ResolverListener paramResolverListener)
    {
      this.listener = paramResolverListener;
      send(0);
    }
  }
}